package com.getpebble.android.bluetooth.radio;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Build.VERSION;
import android.os.ParcelFileDescriptor;
import com.getpebble.android.common.core.trace.Trace;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;

public class PebbleBluetoothSocket {
    private static final String TAG = PebbleBluetoothSocket.class.getSimpleName();
    private BluetoothDevice mBluetoothDevice;
    private BluetoothSocket mBluetoothSocket;

    PebbleBluetoothSocket(BluetoothSocket socket, BluetoothDevice device) {
        this.mBluetoothSocket = socket;
        this.mBluetoothDevice = device;
    }

    public void close() throws IOException {
        Trace.debug(TAG, "close();");
        this.mBluetoothSocket.close();
        try {
            Field field = BluetoothSocket.class.getDeclaredField("mPfd");
            field.setAccessible(true);
            ((ParcelFileDescriptor) field.get(this.mBluetoothSocket)).close();
        } catch (Exception e) {
        }
    }

    public void connect() throws IOException {
        Trace.debug(TAG, "connect();");
        try {
            this.mBluetoothSocket.connect();
        } catch (IOException e) {
            if (VERSION.SDK_INT == 17 || e.getMessage().startsWith("Service discovery failed") || e.getMessage().startsWith("Unable to start Service Discovery")) {
                Trace.debug(TAG, "SDP Workaround... closing socket", e);
                try {
                    this.mBluetoothSocket.close();
                    Trace.debug(TAG, "SDP Workaround... creating socket", e);
                    this.mBluetoothSocket = createRawRfcommSocketHack();
                    if (this.mBluetoothSocket == null) {
                        Trace.info(TAG, "SDK work-around: socket is null");
                        throw e;
                    }
                    Trace.debug(TAG, "connect() from SDK work-around after IOE");
                    this.mBluetoothSocket.connect();
                    return;
                } catch (IOException ec) {
                    Trace.info(TAG, "Error closing socket before SDP work-around");
                    throw ec;
                }
            }
            throw e;
        }
    }

    public InputStream getInputStream() throws IOException {
        Trace.debug(TAG, "getInputStream();");
        return this.mBluetoothSocket.getInputStream();
    }

    public OutputStream getOutputStream() throws IOException {
        Trace.debug(TAG, "getOutputStream();");
        return this.mBluetoothSocket.getOutputStream();
    }

    private BluetoothSocket createRawRfcommSocketHack() {
        try {
            return (BluetoothSocket) this.mBluetoothDevice.getClass().getMethod("createRfcommSocket", new Class[]{Integer.TYPE}).invoke(this.mBluetoothDevice, new Object[]{Integer.valueOf(1)});
        } catch (Exception e) {
            Trace.warning(TAG, "createRawRfcommSocketHack failed", e);
            return null;
        }
    }
}
